<?php
namespace App\Pay\Gateway;

use App\Pay\Config\Config;
use App\Pay\Contracts\GatewayInterface;
use App\Pay\Exceptions\GatewayException;
use App\Pay\Exceptions\InvalidArgumentException;
use App\Pay\Exceptions\InvalidSignException;
use App\Pay\Gateway\Alipay\Sign;
use Illuminate\Support\Facades\Log;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;

class Alipay implements GatewayInterface
{

    /**
     * @var array
     */
    protected $payload = [];

    /**
     * @var Config
     */
    protected $config;


    /**
     * mode
     */
    const MODE_DEV = 'dev';

    /**
     * mode
     */
    const MODE_NORMAL = 'normal';

    /**
     * gateway url
     */
    const URL = [
        self::MODE_NORMAL => 'https://openapi.alipay.com/gateway.do',
        self::MODE_DEV    => 'https://openapi.alipaydev.com/gateway.do?charset=utf-8',
    ];

    public function __construct(Config  $config)
    {
        $this->config = $config;
        $this->payload = [
            'app_id' => $this->config->get('mch_id'),
            'method' => '',
            'charset' => 'UTF-8',
            'sign_type' => 'RSA2',
            'timestamp' => date('Y-m-d H:i:s'),
            'version' => '1.0',
            'notify_url' => $this->config->get('notify_url'),
            'biz_content' => '',
            'return_url' => $this->config->get('return_url'),
        ];
        \App\Pay\Gateway\Alipay\Request::instance()->setConfig($this->config);
    }

    public function pay(string $endpoint, array $params)
    {

        $gatewayClass = get_class($this) . '\\' . ucfirst($endpoint) . 'Gateway';
        if (!class_exists($gatewayClass)) {
            throw new GatewayException('Gateway not defind');
        }
        $appid = $this->config->get('mch_id', null);
        $privateKey = $this->config->get('private_key', null);
        $publicKey = $this->config->get('public_key', null);

        // 判断配置参数是否为空
        if (is_null($appid) || is_null($privateKey) || is_null($publicKey)) {
            throw new InvalidArgumentException('Configuration error');
        }

        $this->payload['biz_content'] = json_encode($params + ['product_code' => 'FAST_INSTANT_TRADE_PAY'], JSON_UNESCAPED_UNICODE);
        return (new $gatewayClass())->pay($this->payload);
    }

    public function cancel(array $params)
    {
        // TODO: Implement cancel() method.
    }

    public function close(array $params)
    {
        // TODO: Implement close() method.
    }

    public function query(array $params)
    {
        // TODO: Implement query() method.
    }

    public function refund(array $params)
    {
        // TODO: Implement refund() method.
    }

    public function refundQuery(array $params)
    {
        // TODO: Implement refundQuery() method.
    }

    /**
     * @param null $content
     * @param bool $isRefund
     * @return array|mixed|null
     * @throws InvalidArgumentException
     * @throws InvalidSignException
     */
    public function verify($content = null, $isRefund = false)
    {
        if (is_null($content)) {
            $content = Request::createFromGlobals()->request->all();
        }
        // TODO: 判断来源是不是支付宝
        $result = Sign::checkSign($content);
        if ($result) {
            return $content;
        }
        throw new InvalidSignException('签名错误');
    }

    public function success()
    {
        return new Response('success');
    }
}
